Embedding Python in C - Cross-platform Development
Embedding Python code into C Linux vs Windows techniques.
Sometimes it's handy to spawn a Python shell from within C programs, or to manipulate Python objects easily from there. Here is a way to embed Python code into C code and have it compile into a native binary (or as a library). The only requirements or course are a working Python 2.x or 3.x installation.
Cross-platform Python Embedding tutorial
Create a test file, embed.c
#include <Python.h>
int main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
return 0;
}
Compile & test on Linux x86_64
gcc embed.c $(python-config --cflags --libs) -o embed
./embed
('Today is', 'Tue Jan 27 09:30:30 2015')
Compile & test on Windows64 (or wine). Get our python.exe-config
mingw64-env
$CC embed.c $(wine python C:\\Python27\\python.exe-config --cflags --libs) -o embed.exe
./embed.exe
('Today is', 'Tue Jan 27 09:30:30 2015')
on fail
Cannot find python.exe-config? We made that up to fool Makefiles that embed Python (and make them work with cross-compiling). Name it python.exe-config and put it somewhere in wine's PYTHONPATH. Now such Makefiles should start working.
#!C:\\Python27\python.exe
import sys, subprocess
class ww(object):
def __init__(self, argv):
try:
argv[1]
except IndexError:
pass
else:
try:
p=subprocess.check_output(["winepath","c:\\Python27"]).strip()
q = '/usr/x86_64-w64-mingw32/sys-root/mingw'
except OSError:
p = '/c/Python27'
for x in argv:
if x == '--includes':
sys.stdout.write('-I'+p+'/include')
# change this
if x == '--prefix' or x == '--exec-prefix':
sys.stdout.write(' '+p+'/usr')
if x == '--cflags':
sys.stdout.write(' -I'+p+'/include -I'+q+'/include -D_WIN32_WINNT=0x0501 -DWINVER=0x0501 -DG_OS_WIN32')
if x == '--libs':
sys.stdout.write(' -lpthread -mthreads -lm -lpython27 -L'+p+'/libs -L'+q+'/libs')
if x == '--ldflags':
sys.stdout.write(' -lpthread -mthreads -lm -lpython27 -L'+p+'/Python27/libs -L'+q+'/libs -Xlinker -export-dynamic')
if __name__ == "__main__":
app = ww(sys.argv)
Incompatible libpython27?
ld: skipping incompatible libpython27.a when searching for -lpython27
python27.lib: error adding symbols: File in wrong format
Rebuild Python 2.7's linkable library to a usable format.
cd ~/.wine/drive_c
gendef windows/system32/python27.dll
/usr/bin/x86_64-w64-mingw32-dlltool -D python27.dll -d python27.def -l libpython27.a
References
Embed Python into a Windows application